
#ifndef CONVEXPOLYGON_H_
#define CONVEXPOLYGON_H_

#include "Core.h"
#include "Vector2.h"
#include "Element.h"
#include "Entity.h"

namespace p2 {

enum ConvexPolygonShapeHint
{
    TrianglePolygonShape = 0,
    BoxPolygonShape,
    RegularPolygonShape,
    DiscShape,
    UnknownConvexPolygonShape
};
    
class ConvexPolygon: public Element
{
DECLARE_RTT(ConvexPolygon, Element);

public:
	inline ConvexPolygon(real mass, Vector2<real> localPosition, real localAngle,
		p2Material const& material, uint32 plane, void* userData);
	virtual ~ConvexPolygon();

	static ConvexPolygon* create(real mass, Vector2<real> position, real rotation,
			p2Material const& material, uint32 plane, void* userData);

	/*
	 * Element
	 */
	virtual bool updateShapeData();
	virtual void updateMotionBounds(real64 dT);
	virtual void updateWorldSpace();
	virtual bool contains(Vector2<real> worldPoint);

	int32 getSupportingVertices(Vector2<real> const& nv, uint32 (&svi)[2]);

	void makeTriangle(real halfWidth, real halfHeight);
	void makeBox(real halfWidth, real halfHeight);
	void makeRegular(real halfWidth, real halfHeight, uint32 numSides);

	inline int32 addVertex(real vx, real vy);
	inline void removeVertex(int32 index);

	inline std::vector<Vector2<real> >& getLocalNormals();
	inline std::vector<Vector2<real> >& getLocalVertices();
	inline std::vector<Vector2<real> >& getWorldNormals();
	inline std::vector<Vector2<real> >& getWorldVertices();
    inline ConvexPolygonShapeHint getShapeHint() const;

private:
	std::vector<Vector2<real> > _localNormals;
	std::vector<Vector2<real> > _localVertices;
	std::vector<Vector2<real> > _worldNormals;
	std::vector<Vector2<real> > _worldVertices;
    
    ConvexPolygonShapeHint _shapeHint;
};

inline ConvexPolygon::ConvexPolygon(real mass, Vector2<real> localPosition, real localAngle,
	p2Material const& material, uint32 plane, void* userData)
	:   Element(mass, localPosition, localAngle, material, plane, userData),
        _shapeHint(UnknownConvexPolygonShape)
{
}

inline ConvexPolygonShapeHint ConvexPolygon::getShapeHint() const
{
    return _shapeHint;
}

inline int32 ConvexPolygon::addVertex(real vx, real vy)
{
	int32 index = _localVertices.size();
	_localVertices.push_back(Vector2<real>(vx, vy));
	return index;
}

inline void ConvexPolygon::removeVertex(int32 index)
{
	_localVertices.erase(_localVertices.begin() + index);
}

inline std::vector<Vector2<real> >& ConvexPolygon::getLocalNormals()
{
	return _localNormals;
}

inline std::vector<Vector2<real> >& ConvexPolygon::getLocalVertices()
{
	return _localVertices;
}

inline std::vector<Vector2<real> >& ConvexPolygon::getWorldNormals()
{
	return _worldNormals;
}

inline std::vector<Vector2<real> >& ConvexPolygon::getWorldVertices()
{
	return _worldVertices;
}

}

#endif /* CONVEXPOLYGON_H_ */
